`ifndef Defines_SVH
`define Defines_SVH
`include "CP0Defines.svh"
//`define USE_VERILATOR
`define RstEnable 1'b0
`define R_type  6'b000000
//R_type_function
`define add     6'b100000
`define addu    6'b100001
`define sub     6'b100010
`define subu    6'b100011

`define mult    6'b011000
`define multu   6'b011001
`define div     6'b011010
`define divu    6'b011011

`define sll     6'b000000
`define srl     6'b000010
`define sra     6'b000011
`define sllv    6'b000100
`define srlv    6'b000110
`define srav    6'b000111

`define and_    6'b100100
`define or_     6'b100101
`define xor_    6'b100110
`define nor_    6'b100111

`define slt     6'b101010
`define sltu    6'b101011

`define jalr    6'b001001
`define jr      6'b001000

`define mfhi    6'b010000
`define mflo    6'b010010
`define mthi    6'b010001
`define mtlo    6'b010011

`define break   6'b001101
`define syscall 6'b001100

//end R_type

//I_type_operation
`define lb	  6'b100000
`define lbu   6'b100100
`define lh	  6'b100001
`define lhu   6'b100101
`define lw    6'b100011
`define sb    6'b101000
`define sh    6'b101001
`define sw    6'b101011

`define addi  6'b001000
`define addiu 6'b001001
`define andi  6'b001100
`define ori   6'b001101
`define xori  6'b001110
`define lui   6'b001111

`define slti  6'b001010
`define sltiu 6'b001011

`define beq   6'b000100
`define bne   6'b000101
`define blez  6'b000110
`define bgtz  6'b000111
//end

//b_special_operation
`define b_special 6'b000001
//b_special_(rt?)
`define bltz  5'b00000
`define bgez  5'b00001
`define bgezal 5'b10001
`define bltzal 5'b10000
//end

//j_type_operation
`define j     6'b000010
`define jal   6'b000011
//end

//p_type_operation  (特权指令)
`define P_type 6'b010000        //除了cache指令

`define eret 6'b011000
`define tlbp 6'b001000
`define tlbr 6'b000001
`define tlbwi 6'b000010
`define mfc0 5'b00000
`define mtc0 5'b00100


//control signal

//load or store
`define byte_zero   3'd0 
`define byte_sign   3'd1
`define half_zero   3'd2
`define half_sign   3'd3
`define word        3'd4
//end

//instruction signal
`define calculate       3'd0    //计算类
`define calculate_imm   3'd1    //立即数计算类
`define load            3'd2    //load类
`define store           3'd3    //store类
`define jump_link       3'd4    //jump_link类
`define jump_link_reg   3'd5    //jump_link_reg类
`define branch_flag     3'd6    //branch类
//end

//ALU signal
`define ALU_add     5'd1 
`define ALU_addu    5'd2     
`define ALU_sub     5'd3
`define ALU_subu    5'd4
`define ALU_sll     5'd5
`define ALU_srl     5'd6
`define ALU_sra     5'd7
`define ALU_and     5'd8
`define ALU_or      5'd9
`define ALU_xor     5'd10
`define ALU_nor     5'd11
`define ALU_slt     5'd12
`define ALU_sltu    5'd13
`define ALU_A       5'd14   
`define ALU_B       5'd15
`define ALU_mul     5'd16
`define ALU_mulu    5'd17
`define ALU_div     5'd18
`define ALU_divu    5'd19

`define FlushDisable 1'b0
`define FlushEnable  1'b1

// RegWrite destination
`define RegWrited_Non   3'b000
`define RegWrited_ra    3'b001
`define RegWrited_rt    3'b010
`define RegWrited_rd    3'b011
`define RegWrited_HI    3'b100
`define RegWrited_LO    3'b101
`define RegWrited_HILO  3'b110
`define RegWrited_CP0   3'b111
//0->0 can't write  
//1->$31 
//2->rt 
//3->rd 
//4->HI
//5->LO
//6->HI&LO
//7->CP0
`define SIZE_OF_RAS 8
`define SIZE_OF_INDEX 8
`define SIZE_OF_SET 256

`define T 2'b11
`define WT 2'b10
`define WNT 2'b01
`define NT 2'b00

`define BranchIsNone    3'b000  //不分�?
`define BranchIsCall    3'b001  //jal,jalr
`define BranchIsReturn  3'b010  //jr
`define BranchIsBranch  3'b011  //branch
`define BranchIsJump    3'b100  //jump
typedef struct packed {
    logic [2:0]                Type;     //表示预测的类�?
    logic                      IsTaken;  //表示预测是否跳转
    logic [31:0]               Target;   //表示预测的跳转地�?
    logic [1:0]                Count;    //表示预测时的计数器�??
    logic                      Hit;      //表示预测时BHT是否命中
    logic                      Valid;    //表示预测是否有效
} PredictResult;

typedef struct packed {
    logic [2:0]                Type;     //表示实际的类�?
    logic                      IsTaken;  //表示实际是否跳转
    logic [31:0]               Target;   //表示实际的跳转地�?
    logic [31:0]               PC;       //�?要校准的PC
    logic [1:0]                Count;    //预测该条指令时的Count
    logic                      Hit;      //预测该指令时的BHT_hit
    logic                      Valid;    //预测是否有效
} FactResult;

typedef struct packed {
    logic [31:`SIZE_OF_INDEX+2]Tag;   //PC的Tag
    logic [31:0]               Target;
    logic [2:0]                Type;  //分支种类
    logic [1:0]                Count; //二位饱和计数�?
    logic                      Valid; //有效
} BHT_Entry;

typedef struct packed {
	logic                      Valid;
	logic [31:0]               Addr;
} RAS_EntryType;

typedef struct packed {
    logic [31:`SIZE_OF_INDEX+2]Tag;       //Tag in BHT
    logic [31:`SIZE_OF_INDEX+2]PCTag;     //Tag of PC
    logic [31:0]               BHT_Addr;  //Target Address in BHT
    RAS_EntryType              RAS_Entry; //Target Address in RAS
    logic [31:0]               PC_Add8;   //pc+8(return的地�?)
    logic [2:0]                Type;      //Type in BHT(分支种类)
    logic [1:0]                Count;     //Count in BHT(饱和计数�?)
	logic                      Valid;
} BPU_RegType;
//TLB destination signal
typedef enum logic [1:0] { 
    NoTLB,
    TLBWI,
    TLBR,
    TLBP
 } E_TLB;
`endif